#include "IRC_core.h"

static struct IRC_core *IRC_core_t = NULL; //Only one instance of this is accepted
static void handle_notification( char *msg );

static int exec()
{
	printf("Launching llamabot...\n");

	pthread_join( IRC_core_t->input_thread_t->thread,  NULL );
	pthread_join( IRC_core_t->output_thread_t->thread, NULL );

	printf("Cleaning...\n");

	delete_IRC_core();

	pthread_exit(NULL); /*Must be called, otherwise memory leaks occur when pthread is used*/

	return EXIT_SUCCESS; /*Basically, this is not called*/
}

struct IRC_core * new_IRC_core( char *server, char *_port ) 
{
	int port;

	if ( !(port = atoi( _port )) ) {
		fprintf(stderr, "Invalid port number\n");		
		return NULL;
	}

	if ( !IRC_core_t )
		IRC_core_t = (struct IRC_core*) malloc( sizeof( struct IRC_core ) );
	
	IRC_core_t->exec = exec;

	IRC_core_t->socket_t = new_socket( server, _port );
	if ( IRC_core_t->socket_t == NULL ) {
		fprintf(stderr, "Failed to create socket.\n");
		return NULL;
	}

	IRC_core_t->input_thread_t = new_input_thread( IRC_core_t );
	if ( IRC_core_t->input_thread_t == NULL ) {
		fprintf(stderr, "Failed to create input thread.\n");
		return NULL;
	}

	IRC_core_t->output_thread_t = new_output_thread( IRC_core_t );
	if ( IRC_core_t->output_thread_t == NULL ) {
		fprintf(stderr, "Failed to create output thread.\n");
		return NULL;
	}

	IRC_core_t->plugin_control_t = new_plugin_control( handle_notification );
	if ( IRC_core_t->plugin_control_t == NULL ) {
		fprintf(stderr, "Failed to create plugin control.\n");
		return NULL;
	}

	IRC_core_t->plugin_control_t->core_plugin_t->plugin->send_message = send_message;
	IRC_core_t->plugin_control_t->send_message = send_message;
	IRC_core_t->input_thread_t->plugin_list = IRC_core_t->plugin_control_t->plugin_list;

	return IRC_core_t;
}

void delete_IRC_core() 
{
	if ( IRC_core_t ) {
		delete_socket( IRC_core_t->socket_t );
		delete_input_thread();
		delete_output_thread(); 
		delete_plugin_control();
		free( IRC_core_t );
		IRC_core_t = NULL;
	}
}

void host_disconnected_IRC_core() 
{
	IRC_core_t->output_thread_t->is_running = 0;
	IRC_core_t->input_thread_t->is_running = 0;
	wake_up_output_thread();
}

static void handle_notification( char *msg ) 
{
	if ( !strncmp( msg, "/quit", 5 ) ) {
		printf("User typed /quit\n");	
		shutdown( IRC_core_t->socket_t->sockfd, 2 );
		host_disconnected_IRC_core();
	}
}
